﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;

namespace FinApp.Core {

    public abstract class SingletonBase : IDisposable {

        #region Static Members
        private static readonly List<SingletonBase> singletons = new List<SingletonBase>();
        #endregion

        #region Static Methods
        public static void ClearAllSingletons() {
            lock (singletons) {
                //foreach (var s in Singletons) {
                // note that linq is not used because of winrt!
                singletons.ForEach(s => s.Dispose());
                //    s.Dispose();
                //}

                singletons.Clear();
            }
        }
        #endregion

        #region Constructors
        protected SingletonBase() {
            lock (singletons) {
                singletons.Add(this);
            }
        }
        #endregion

        #region Destructors
        ~SingletonBase() {
            Dispose(false);
        }
        #endregion

        #region Methods of IDisposable
        public void Dispose() {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected abstract void Dispose(bool isDisposing);
        #endregion

    }

    public abstract class Singleton<TInterface> : SingletonBase 
        where TInterface : new() {

        private static TInterface instance = new TInterface();

        #region Constructors
        protected Singleton() {

        }
        #endregion

        #region Singleton Properties
        /// <summary>
        /// Obtiene la instancia de la factoría
        /// </summary>
        public static TInterface Instance { 
            get { return instance; }
        }
        #endregion

        #region Method Overrides
        protected override void Dispose(bool isDisposing) {
            if (isDisposing) {
                instance = default(TInterface);
            }
        } 
        #endregion

    }

}
